/*
 * VEML6046X00_RGB.c
 *
 * Created  : 6 March 2023
 * Modified : 2 June 2023
 * Author   : HWanyusof
 * Version	: 1.3
 */

#include "VEML6046X00_Prototypes.h"
#include "VEML6046X00.h"
#include "I2C_Functions.h"
#include "VEML6046X00_Application_Library.h"

extern int I2C_Bus;

//****************************************************************************************************
//*****************************************Sensor API*************************************************

/*Switch the sensor on/off
 *VEML6046X00_SET_RGB_ON_0(Byte RGB_ON_0_Bit)
 *Byte RGB_ON_0_Bit - Input Parameter:
 *
 * VEML6046X00_RGB_ON_0_DIS
 * VEML6046X00_RGB_ON_0_EN
 *
 */
void VEML6046X00_SET_RGB_ON_0(Byte RGB_ON_0_Bit)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = (VEML6046X00_Data.RData[0]&~(VEML6046X00_RGB_ON_0_DIS|VEML6046X00_RGB_ON_0_EN))|RGB_ON_0_Bit;
	VEML6046X00_Data.WData[1] = VEML6046X00_Data.RData[1];
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Switch the sensor on/off
 *VEML6046X00_SET_RGB_ON_1(Byte RGB_ON_1_Bit)
 *Byte RGB_ON_1_Bit - Input Parameter:
 *
 * VEML6046X00_RGB_ON_1_DIS
 * VEML6046X00_RGB_ON_1_EN
 *
 */
void VEML6046X00_SET_RGB_ON_1(Byte RGB_ON_1_Bit)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = VEML6046X00_Data.RData[0];
	VEML6046X00_Data.WData[1] = (VEML6046X00_Data.RData[1]&~(VEML6046X00_RGB_ON_1_DIS|VEML6046X00_RGB_ON_1_EN))|RGB_ON_1_Bit;
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the Integration Time
 *VEML6046X00_SET_RGB_IT(Byte IntTime)
 *Byte IntTime - Input Parameter:
 *
 * VEML6046X00_RGB_IT_3_125ms
 * VEML6046X00_RGB_IT_6_25ms
 * VEML6046X00_RGB_IT_12_5ms
 * VEML6046X00_RGB_IT_25ms
 * VEML6046X00_RGB_IT_50ms
 * VEML6046X00_RGB_IT_100ms
 * VEML6046X00_RGB_IT_200ms
 * VEML6046X00_RGB_IT_400ms
 */
void VEML6046X00_SET_RGB_IT(Byte IntTime)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = (VEML6046X00_Data.RData[0]&~(VEML6046X00_RGB_IT_3_125ms|VEML6046X00_RGB_IT_6_25ms|VEML6046X00_RGB_IT_12_5ms|VEML6046X00_RGB_IT_25ms|VEML6046X00_RGB_IT_50ms|VEML6046X00_RGB_IT_100ms|VEML6046X00_RGB_IT_200ms|VEML6046X00_RGB_IT_400ms))|IntTime;
	VEML6046X00_Data.WData[1] = VEML6046X00_Data.RData[1];
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the measurement mode of the sensor
 *VEML6046X00_SET_RGB_MODE(Byte Mode)
 *Byte Mode - Input Parameter:
 *
 * VEML6046X00_RGB_AUTO_MODE
 * VEML6046X00_RGB_AF_MODE
 */
void VEML6046X00_SET_RGB_MODE(Byte Mode)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress =  VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
    ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] =(VEML6046X00_Data.RData[0]&~(VEML6046X00_RGB_AUTO_MODE|VEML6046X00_RGB_AF_MODE))|Mode;
	VEML6046X00_Data.WData[1] = VEML6046X00_Data.RData[1];
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the active force mode trigger
 *VEML6046X00_SET_RGB_TRIG(Byte TriggerBit)
 *Byte TriggerBit - Input Parameter:
 *
 * VEML6046X00_RGB_TRIG_DIS
 * VEML6046X00_RGB_TRIG_EN
 */
void VEML6046X00_SET_RGB_TRIG(Byte TriggerBit)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress =  VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
    ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] =(VEML6046X00_Data.RData[0]&~(VEML6046X00_RGB_TRIG_DIS|VEML6046X00_RGB_TRIG_EN))|TriggerBit;
	VEML6046X00_Data.WData[1] = VEML6046X00_Data.RData[1];
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Enable / disable the green channel interrupt
 *VEML6046X00_SET_RGB_INT(Byte Interrupt)
 *Byte Interrupt - Input Parameter:
 *
 * VEML6046X00_RGB_INT_DIS
 * VEML6046X00_RGB_INT_EN
 */
void VEML6046X00_SET_RGB_INT(Byte Interrupt)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = (VEML6046X00_Data.RData[0]&~(VEML6046X00_RGB_INT_DIS|VEML6046X00_RGB_INT_EN))|Interrupt;
	VEML6046X00_Data.WData[1] = VEML6046X00_Data.RData[1];
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the effective photodiode size for the R,G,B and IR channel
 *VEML6046X00_SET_PD_DIV(Byte PD_Size)
 *Byte PD_Size - Input Parameter:
 *
 * VEML6046X00_PD_DIV_FULL
 * VEML6046X00_PD_DIV_HALF
 */
void VEML6046X00_SET_PD_DIV(Byte PD_Size)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = (VEML6046X00_Data.RData[0]);
	VEML6046X00_Data.WData[1] = (VEML6046X00_Data.RData[1]&~(VEML6046X00_PD_DIV_FULL|VEML6046X00_PD_DIV_HALF))|PD_Size;
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the gain of the RGB
 *VEML6046X00_SET_RGB_GAIN(Byte Gain)
 *Byte Gain - Input Parameter:
 *
 * VEML6046X00_RGB_GAIN_x0_5
 * VEML6046X00_RGB_GAIN_x0_66
 * VEML6046X00_RGB_GAIN_x1
 * VEML6046X00_RGB_GAIN_x2
 */
void VEML6046X00_SET_RGB_GAIN(Byte Gain)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = VEML6046X00_Data.RData[0];
	VEML6046X00_Data.WData[1] = (VEML6046X00_Data.RData[1]&~(VEML6046X00_RGB_GAIN_x1|VEML6046X00_RGB_GAIN_x2|VEML6046X00_RGB_GAIN_x0_66|VEML6046X00_RGB_GAIN_x0_5))|(Gain);
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the amount of consecutive threshold crossing events necessary to trigger the green channel interrupt
 *VEML6046X00_SET_RGB_PERS(Byte Pers)
 *Byte Pers - Input Parameter:
 *
 * VEML6046X00_RGB_PERS_1
 * VEML6046X00_RGB_PERS_2
 * VEML6046X00_RGB_PERS_4
 * VEML6046X00_RGB_PERS_8
 */
void VEML6046X00_SET_RGB_PERS(Byte Pers)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = (VEML6046X00_Data.RData[0]);
	VEML6046X00_Data.WData[1] = (VEML6046X00_Data.RData[1]&~(VEML6046X00_RGB_PERS_1|VEML6046X00_RGB_PERS_2|VEML6046X00_RGB_PERS_4|VEML6046X00_RGB_PERS_8))|Pers;
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the internal calibration after power on
 *VEML6046X00_SET_RGB_CAL(Byte rgb_cal)
 *Byte rgb_cal - Input Parameter:
 *
 * VEML6046X00_RGB_CAL_OFF
 * VEML6046X00_RGB_CAL_ON
 */
void VEML6046X00_SET_RGB_CAL(Byte rgb_cal)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	VEML6046X00_Data.WData[0] = (VEML6046X00_Data.RData[0]);
	VEML6046X00_Data.WData[1] = (VEML6046X00_Data.RData[1]&~(VEML6046X00_RGB_CAL_OFF|VEML6046X00_RGB_CAL_ON))|rgb_cal;
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the high threshold green channel interrupt value
 *VEML6046X00_SET_RGB_HighThreshold(Word HighThreshold)
 *Word HighThreshold - Input Parameter:
 *
 * Value between 0d0 and 0d65535
 */
void VEML6046X00_SET_RGB_HighThreshold(Word HighThreshold)
{
 	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_THDH_L;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	VEML6046X00_Data.WData[0] = HighThreshold;
	VEML6046X00_Data.WData[1] = (HighThreshold>>8);
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Set the low threshold green channel interrupt value
 *VEML6046X00_SET_RGB_LowThreshold(Word LowThreshold)
 *Word LowThreshold - Input Parameter:
 *
 * Value between 0d0 and 0d65535
 */
void VEML6046X00_SET_RGB_LowThreshold(Word LowThreshold)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_THDL_L;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	VEML6046X00_Data.WData[0] = LowThreshold;
	VEML6046X00_Data.WData[1] = (LowThreshold>>8);
	WriteI2C_Bus(&VEML6046X00_Data);
}

/*Read the red channel output data
 *VEML6046X00_GET_R_DATA() returns Red Channel Data between 0d0 and 0d65535
 */
Word VEML6046X00_GET_R_DATA()
{
	int RData=0;
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_R_DATA_L;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	RData=((VEML6046X00_Data.RData[1]<<8)|VEML6046X00_Data.RData[0]);
	return RData;
}

/*Read the green channel output data
 *VEML6046X00_GET_G_DATA() returns Green Channel Data between 0d0 and 0d65535
 */
Word VEML6046X00_GET_G_DATA()
{
	int RData=0;
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_G_DATA_L;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	RData = ((VEML6046X00_Data.RData[1]<<8)|VEML6046X00_Data.RData[0]);
	return RData;
}

/*Read the blue channel output data
 *VEML6046X00_GET_B_DATA() returns Blue Channel Data between 0d0 and 0d65535
 */
Word VEML6046X00_GET_B_DATA()
{
	int RData=0;
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_B_DATA_L;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	RData = ((VEML6046X00_Data.RData[1]<<8)|VEML6046X00_Data.RData[0]);
	return RData;
}

/*Read the IR channel output data
 *VEML6046X00_GET_IR_DATA() returns IR Channel Data between 0d0 and 0d65535
 */
Word VEML6046X00_GET_IR_DATA()
{
	int RData=0;
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_IR_DATA_L;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	RData = ((VEML6046X00_Data.RData[1]<<8)|VEML6046X00_Data.RData[0]);
	return RData;
}

/*Read Device ID
 *Returns ID
 */
Word VEML6046X00_GET_ID()
{
	Word RegValue;
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_ID_L;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	RegValue = VEML6046X00_Data.RData[1]<<8|VEML6046X00_Data.RData[0];
	return RegValue;
}

/*Read the RGB Interrupt Flag
 *VEML6046X00_GET_INT_FLAG() returns interrupt flag status.
 *Please refer to Table 11 in the Datasheet page 11
 */
Byte VEML6046X00_GET_INT_FLAG()
{
	uint8_t RData;
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_INT_FLAG;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
    RData = (VEML6046X00_Data.RData[0]);
	return RData;
}

/*Read register value
 *VEML6046X00_READ_Reg(Byte Reg)
 *Byte Reg - Input Parameter:
 *
 * VEML6046X00_RGB_CONF_0		0x00
 * VEML6046X00_RGB_THDH_L		0x04
 * VEML6046X00_RGB_THDL_L	    0x06
 * VEML6046X00_R_DATA_L	        0x10
 * VEML6046X00_G_DATA_L	        0x12
 * VEML6046X00_B_DATA_L	        0x14
 * VEML6046X00_IR_DATA_L	    0x16
 * VEML6046X00_ID_L		        0x18
 * VEML6046X00_INT_FLAG		    0x1B
 *
 *returns Register Value between 0d0/0x00 and 0d65535/0xFFFF
 */
Word VEML6046X00_READ_Reg(Byte Reg)
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = Reg;
	VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	return (VEML6046X00_Data.RData[1]<<8|VEML6046X00_Data.RData[0]);
}

/*Read the RGB_ON_0 bit
 *returns 1 for Shutdown and 0 for Sensor On
 */
bool VEML6046X00_GET_RGB_ON_0_Bit()
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
    VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	return (VEML6046X00_Data.RData[0] & 0x01);
}

/*Read the RGB_ON_1 bit
 *returns 1 for Shutdown and 0 for Sensor On
 */
bool VEML6046X00_GET_RGB_ON_1_Bit()
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_1;
    VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	return (VEML6046X00_Data.RData[0] & 0x80);
}

/*Read the RGB_MODE bit
 *returns 1 for AF Mode and 0 for Auto Mode
 */
bool VEML6046X00_GET_RGB_MODE_Bit()
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
    VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	return (VEML6046X00_Data.RData[0] & 0x08);
}

/*Read the RGB_IT bits
 *returns 0d0 - 0d8 depending on RGB_IT bits
 */
int VEML6046X00_GET_RGB_IT_Bits()
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
    VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x00) {return 1;}
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x10) {return 2;}
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x20) {return 3;}
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x30) {return 4;}
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x40) {return 5;}
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x50) {return 6;}
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x60) {return 7;}
	if ((VEML6046X00_Data.RData[0] & 0x70) == 0x70) {return 8;}
	else
	return 0;
}

/*Read the RGB_GAIN bits
 *returns 0d0 - 0d4 depending on RGB_GAIN bits
 */
int VEML6046X00_GET_RGB_GAIN_Bits()
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
    VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	if ((VEML6046X00_Data.RData[1] & 0x18) == 0x00) {return 1;}
	if ((VEML6046X00_Data.RData[1] & 0x18) == 0x08) {return 2;}
	if ((VEML6046X00_Data.RData[1] & 0x18) == 0x10) {return 3;}
	if ((VEML6046X00_Data.RData[1] & 0x18) == 0x18) {return 4;}
	else
	return 0;
}

/*Read the PD_DIV bits
 *returns 1 for 1/2 PD size being used and 0 for full (2/2) PD size being used
 */
bool VEML6046X00_GET_PD_DIV_Bits()
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_RGB_CONF_0;
    VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	return (VEML6046X00_Data.RData[1] & 0x40);
}

/*Read the AF_DATA_READY flag
 *returns 1 for AF_DATA_READY flag and 0 for no AF_DATA_READY flag
 */
bool VEML6046X00_GET_AF_DATA_READY_FLAG()
{
	struct TransferData VEML6046X00_Data;
	VEML6046X00_Data.Slave_Address = VEML6046X00_Slave_Address;
	VEML6046X00_Data.RegisterAddress = VEML6046X00_INT_FLAG;
    VEML6046X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6046X00_Data);
	return (VEML6046X00_Data.RData[0] & 0x08);
}
